<?php

require_once( "classes/orm/StoredObject.php" );
require_once( "classes/orm/Property.php" );

/**
 * Хранилище объектов на основе реляционной базы данных
 * 
 * @author alno
 */
class DbStorage {
	
	/**
	 * Загрузить объект из БД
	 *
	 * @param StoredObject $obj объект, в который загрузить данные
	 * @return StoredObject загруженный объект
	 */
	function loadObject( &$obj ) {
		
		// Запрос к БД
		$query = $this->query( "SELECT * FROM ".$obj->table." WHERE id = '".(int)$obj->id."'" );
		
		// Получить объект из запроса
		$data = $this->fetch( $query );
		
		// Сохранить данные в объект
		$obj->mergeFromArray( $data );
		
		// Связываем объект с текущим хранилищем
		$obj->storage =& $this;
		
		return $obj;
	}
	
	/**
	 * Найти объект в хранилище по SQL выражению
	 *
	 * @param StoredObject $obj объект, в который загрузить данные
	 * @param String $exp выражение для поиска
	 * @return StoredObject загруженный объект
	 */
	function findObject( &$obj, $exp ) {
		
		// Запрос к БД
		$query = $this->query( "SELECT * FROM ".$obj->table." WHERE ".$exp );
		
		// Получить объект из запроса
		$data = $this->fetch( $query );
		
		// Сохранить данные в объект
		$obj->mergeFromArray( $data );
		
		// Связываем объект с текущим хранилищем
		$obj->storage =& $this;
		
		return $obj;		
	}
	
	/**
	 * Найти объекты в хранилище по SQL выражению
	 *
	 * @param StoredObject $obj объект, в который загрузить данные
	 * @param String $exp выражение для поиска
	 * @return Array загруженные объекты
	 */
	function findObjects( $objectClass, $exp ) {
		
		// Запрос к БД
		$query = $this->query( "SELECT * FROM ".call_user_func( array( $objectClass, 'getTable' ) )." WHERE ".$exp );
		
		$res = array();
		
		// Получить объекты из запроса
		while ( $data = $this->fetch( $query ) ) {
			$obj = new $objectClass;
			
			// Сохранить данные в объект
			$obj->mergeFromArray( $data );
			
			// Связываем объект с текущим хранилищем
			$obj->storage =& $this;
			
			// Добавляем объект в список результатов
			array_push( $res, $obj );
		}
		
		return $res;		
	}
	
	/**
	 * Сохранить объект в БД
	 *
	 * @param StoredObject $obj объект, который необходимо сохранить
	 * @return StoredObject сохраненный объект
	 */
	function saveObject( &$obj ) {
		$sql = "UPDATE ".$obj->table." SET ";
		
		$first = true;
		foreach( $obj->properties as $propname => $propvalue ) {
			if ( !$first ) $sql .= ", ";			
			$first = false;
			
			$sql .= $propname." = '".addslashes( $propvalue->get() )."'";
		}
		
		$sql .= " WHERE id = '".(int)$obj->id."'";
		
		// Запрос к БД
		$this->query( $sql );
		
		// Связываем объект с текущим хранилищем
		$obj->storage =& $this;
		
		return $obj;
	}
	
	/**
	 * Создать объект в БД
	 *
	 * @param StoredObject $obj объект, который необходимо создать
	 * @return StoredObject созданный объект
	 */
	function createObject( &$obj ) {
		$sql = "INSERT INTO ".$obj->table." ( ";
		
		$first = true;
		foreach( $obj->properties as $propname => $propvalue ) {
			if ( !$first ) $sql .= ", ";			
			$first = false;
			
			$sql .= $propname;
		}
		
		$sql .= " ) VALUES ( ";
		
		$first = true;
		foreach( $obj->properties as $propname => $propvalue ) {
			if ( !$first ) $sql .= ", ";			
			$first = false;
			
			$sql .= "'".addslashes( $propvalue->get() )."'";
		}
		
		$sql .= " )";
		
		// Запрос к БД
		$this->query( $sql );
		
		// Устанавливаем идентификатор объекта
		$obj->id = $this->getInsertedId();
		
		// Связываем объект с текущим хранилищем
		$obj->storage =& $this;
		
		return $obj;
	}
	
	/**
	 * Удалить объект из БД
	 *
	 * @param StoredObject $obj объект, который необходимо удалить
	 */
	function removeObject( $obj ) {
		$this->query( "DELETE FROM ".$obj->table." WHERE id = '".(int)$obj->id."'" );
	}
}
?>
